#ifndef __COMMON_H__
#define __COMMON_H__

#define DEBUG_NO		0
#define DEBUG_INFO		1
#define DEBUG_VERBOSE	2

#define DEBUG_LEVEL		DEBUG_VERBOSE
#define OPT_BUILD

#include <stdlib.h>
#include <string>
#include <stdio.h>
#include <cstdlib>


#ifdef OPT_BUILD
	#if DEBUG_LEVEL==DEBUG_VERBOSE_DBG
		#define IF_DBG_VERB_DBG(s)	s
		#define	IF_DBG_VERB(s)		s
		#define	IF_DBG_INFO(s)		s
	#elif DEBUG_LEVEL==DEBUG_VERBOSE
		#define IF_DBG_VERB_DBG(s)
		#define	IF_DBG_VERB(s)	s
		#define	IF_DBG_INFO(s)	s
	#elif	DEBUG_LEVEL==DEBUG_INFO
		#define IF_DBG_VERB_DBG(s)
		#define	IF_DBG_VERB(s)
		#define	IF_DBG_INFO(s)	s
	#elif	DEBUG_LEVEL==DEBUG_NO
		#define	IF_DBG_VERB_DBG(s)
		#define IF_DBG_VERB(s)
		#define IF_DBG_INFO(s)
	#endif

#else
	#define		IF_DBG_VERB_DBG(s)
	#define 	IF_DBG_VERB(s)
	#define 	IF_DBG_INFO(s)
#endif

#define MIN(a,b) ((a)<(b) ? (a) : (b))
#define MAX(a,b) ((a)>(b) ? (a) : (b))
#define ABS(val) ( ((val)>=0) ? (val) : -(val) )

#define NORM_RAND	(rand()/(float)RAND_MAX)

using namespace std;

typedef unsigned char  HERAuint8;
typedef unsigned short HERAuint16;
typedef unsigned long  HERAuint32;

/** \class  utils
 *  \brief  Insieme di funzioni di supporto non appartenenti a degli specifici moduli.
 */
class utils{
public:
    /** Crea una stringa contenente la rappresentazione binaria del byte specificato.
     *
     *  \param[in]  byte    Byte da convertire
     *  \param[out] buff    Stringa nella quale inserire la rappresentazione binaria
     */
    static void binarizza(HERAuint8 byte,char *buff);

    /** Crea una stringa contenente la rappresentazione binaria dell'area di memoria specificata
     *
     *  \param[in]  buf     Puntatore all'area contenente i dati da convertire
     *  \param[in]  size    Dimensione dell'area da convertire
     *  \param[out] str     Stringa nella quale inserire la rappresentazione binaria
     */
    static void bin_string(const HERAuint8 *buf, int size,char *str);

    /** Calcola la distanza di hamming tra le due aree di memoria specificate.
     *
     *  \param[in]  b1          Area di memoria 1
     *  \param[in]  b2          Area di memoria 2
     *  \param[in]  len         Numero di bytes contenuti delle aree specificate
     *  \param[in]  n_lastbits  Numero di bit dell'ultimo byte da considerare
     *  \return                 Distanza di hamming tra le due aree di memoria
     */
    static int  hamming_dist(const HERAuint8 *b1,const HERAuint8 *b2,int len,int n_lastbits);

};

/** \class EHW_Exception
 *  \brief Generica eccezione lanciata dai moduli del framework
 */
class EHW_Exception
{
    public:
    //! Messaggio d'errore
    string msg;
    /** Inizializza il messaggio con il testo specificato
     *  \param[in] mess Messaggio d'errore
     */
    EHW_Exception(char *mess) {msg.assign(mess);}
};
#endif
